package vn.nt.healthcare.server.ws.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import vn.nt.healthcare.server.ws.domain.AppUser;
import vn.nt.healthcare.server.ws.domain.Company;
import vn.nt.healthcare.server.ws.domain.Location;
import vn.nt.healthcare.server.ws.domain.Session;
import vn.nt.healthcare.server.ws.domain.User;
import vn.nt.healthcare.server.ws.domain.UserSetting;
import vn.nt.healthcare.server.ws.model.CompanyInfo;
import vn.nt.healthcare.server.ws.model.LoginInfo;
import vn.nt.healthcare.server.ws.repositories.AppUserRepository;
import vn.nt.healthcare.server.ws.repositories.CompanyRepository;
import vn.nt.healthcare.server.ws.repositories.LocationRepository;
import vn.nt.healthcare.server.ws.repositories.SessionRepository;
import vn.nt.healthcare.server.ws.repositories.UserRepository;
import vn.nt.healthcare.server.ws.service.UserService;
import vn.nt.healthcare.server.ws.util.CompanyUtil;
import vn.nt.healthcare.server.ws.util.Constants;

@Service("userService")
public class UserServiceImpl implements UserService, Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3576137558140511877L;
	@Autowired
	private UserRepository userRepository;
	@Autowired
	private SessionRepository sessionRepository;
	@Autowired
	private CompanyRepository companyRepository;
	@Autowired
	private LocationRepository locationRepository;
	@Autowired
	private AppUserRepository appUserRepository;

	@Override
	public User findUserByUuidAndPassword(String uuid, String password) {
		User user = userRepository.findByUuidAndPassword(uuid, password);
		return user;
	}

	@Override
	public LoginInfo login(String uuid, String password) {
		User userLogin = userRepository.findByUuidAndPassword(uuid, password);
		if (userLogin == null) {
			return initLoginInfo("", "", "", Constants.LOGIN_FAILED_USER_PASS);
		} else {
			// save session in login per time
			String sid = UUID.randomUUID().toString();
			userLogin.setSid(sid);
			userRepository.save(userLogin);

			// add into session
			sessionRepository.save(initSession(sid, userLogin));
		}
		return initLoginInfo(
				userLogin.getFirstname() + " " + userLogin.getLastname(),
				userLogin.getUuid(), userLogin.getSid(),
				Constants.LOGIN_SUCCESS);
	}

	@Override
	public List<CompanyInfo> findCompanies(String uuid, String password) {
		// TODO Auto-generated method stub
		User found = userRepository.findByUuidAndPassword(uuid, password);
		if (found != null) {
			ArrayList<CompanyInfo> arrayCompanies = new ArrayList<CompanyInfo>();
			List<Company> companies = companyRepository.findByUuid(found
					.getUuid());
			if (!CollectionUtils.isEmpty(companies)) {
				for (Company company : companies) {
					List<Location> location = company.getLocations();
					arrayCompanies.add(CompanyUtil.initCompanyInfo(location,
							company));
				}
				return arrayCompanies;
			}
		}
		return null;
	}

	@Override
	public List<CompanyInfo> findCompanies(String sid) {
		// TODO Auto-generated method stub
		Session session = sessionRepository.findBySid(sid);
		if (session != null) {
			List<CompanyInfo> arrayCompanies = new ArrayList<CompanyInfo>();
			List<Company> companies = companyRepository.findByUuid(session
					.getUuid());
			if (!CollectionUtils.isEmpty(companies)) {
				for (Company company : companies) {
					List<Location> location = company.getLocations();
					arrayCompanies.add(CompanyUtil.initCompanyInfo(location,
							company));
				}
				return arrayCompanies;
			}
		}
		return null;
	}

	private LoginInfo initLoginInfo(String username, String uuid, String sid,
			String loginStatus) {
		LoginInfo loginInfo = new LoginInfo();
		loginInfo.setLoginStatus(loginStatus);
		loginInfo.setSid(sid);
		loginInfo.setUuid(uuid);
		loginInfo.setUsername(username);
		return loginInfo;
	}

	private Session initSession(String sid, User user) {
		Session session = new Session();
		Calendar c = Calendar.getInstance();
		session.setSid(sid);
		session.setUuid(user.getUuid());
		session.setTimestamp(c.getTime());
		session.setTimestampL(c.getTimeInMillis());
		return session;
	}

	@Override
	public LoginInfo register(UserSetting userInfo) {
		// TODO Auto-generated method stub
		User user = new User();
		user.setBirthday(userInfo.getBirthday());
		user.setFirstname(userInfo.getFirstname());
		user.setLastname(userInfo.getLastname());
		user.setEmail(userInfo.getEmail());
		user.setPassword(userInfo.getPassword());
		user.setMobile(userInfo.getMobile());
		String sid = UUID.randomUUID().toString();
		user.setUuid(sid);
		user.setState(Constants.ACTIVE);
		userRepository.save(user);
		return initLoginInfo(userInfo.getUsername(), userInfo.getPassword(),
				sid, Constants.REGISTER_SUCCESSFULLY);
	}

	@Override
	public LoginInfo registerPush(UserSetting userInfo, String os,
			String token, String app) {
		User user = new User();
		user.setBirthday(userInfo.getBirthday());
		user.setFirstname(userInfo.getFirstname());
		user.setLastname(userInfo.getLastname());
		user.setEmail(userInfo.getEmail());
		user.setPassword(userInfo.getPassword());
		user.setMobile(userInfo.getMobile());
		String sid = UUID.randomUUID().toString();
		user.setUuid(sid);
		user.setState(Constants.ACTIVE);
		userRepository.save(user);
		AppUser appUser = new AppUser();
		appUser.setCreatedDate(new Date());
		appUser.setOs(os);
		appUser.setToken(token);
		appUser.setApp_name(app);
		appUserRepository.save(appUser);
		return initLoginInfo(userInfo.getUsername(), userInfo.getPassword(),
				sid, Constants.REGISTER_SUCCESSFULLY);
	}

	@Override
	public LoginInfo loginUser(String username, String password) {
		// TODO Auto-generated method stub
		User userLogin = userRepository.findUserByUsernameAndPassword(username,
				password);
		if (userLogin == null) {
			return initLoginInfo("", "", "", Constants.LOGIN_FAILED_USER_PASS);
		} else {
			// save session in login per time
			String sid = UUID.randomUUID().toString();
			userLogin.setSid(sid);
			userRepository.save(userLogin);
			// add into session
			sessionRepository.save(initSession(sid, userLogin));
		}
		return initLoginInfo(
				userLogin.getFirstname() + " " + userLogin.getLastname(),
				userLogin.getUuid(), userLogin.getSid(),
				Constants.LOGIN_SUCCESS);
	}

}
